package com.css.economy.evaluate.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.css.attachment.entity.AttachmentInfoEntity;
import com.css.attachment.entity.ParsingResult;
import com.css.attachment.service.AttachmentService;
import com.css.attachment.vo.AttachVO;
import com.css.economy.evaluate.entity.BuildingLossMatrix;
import com.css.economy.evaluate.entity.EconomyBuildingPrice;
import com.css.economy.evaluate.entity.EconomyModel;
import com.css.economy.evaluate.mapper.EconomyModelMapper;
import com.css.economy.evaluate.service.BuildingLossMatrixService;
import com.css.economy.evaluate.service.EconomyBuildingPriceService;
import com.css.economy.evaluate.service.EconomyModelService;
import com.css.enums.GeomTypeEnum;
import com.css.util.ShpAnalyticUtil;
import com.css.util.ZipUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.postgis.Geometry;
import org.postgis.PGgeometry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Dbj
 * @date 2024年09月23日  9:26
 */
@Service
public class EconomyModelServiceImpl extends ServiceImpl<EconomyModelMapper, EconomyModel> implements EconomyModelService {

    @Resource
    BuildingLossMatrixService buildingLossMatrixService;
    @Resource
    AttachmentService attachmentService;
    @Resource
    EconomyBuildingPriceService economyBuildingPriceService;

    /**
     * 保存建筑物模型数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateModelData(EconomyModel economyModel) throws Exception {
        economyModel.setUpdateUserTime(DateUtil.date());
        EconomyModel one = this.getBaseMapper().selectOne(null);
        if(!one.getAttachId().equals(economyModel.getAttachId())){
            //解析建筑物造价数据zip
            analAndsaveBuildingPriceData(economyModel.getAttachId());
        }
        //线删除之前保存的建筑物损失比矩阵
        buildingLossMatrixService.remove(null);
        //保存新的建筑物损失比矩阵
        List<BuildingLossMatrix> list = economyModel.getList();
        for (int i = list.size() - 1; i >= 0; i--) {
            BuildingLossMatrix buildingLossMatrix = list.get(i);
            buildingLossMatrix.setId(i+"");
        }
        if(ObjectUtils.isNotEmpty(list) && list.size()>0){
            buildingLossMatrixService.saveBatch(list);
        }
        this.saveOrUpdate(economyModel);
    }


    /**
     * 解析和保存建筑物造价数据
     */
    private void analAndsaveBuildingPriceData(String attachId) throws Exception {
        AttachmentInfoEntity attach = attachmentService.getAttach(attachId);
        //获取解析数据
        ParsingResult shpData = analysisShp(attach);
        List<EconomyBuildingPrice> priceList = getList(shpData.getShpList());
        economyBuildingPriceService.remove(null);
        if(priceList.size()>0){
            economyBuildingPriceService.saveBatch(priceList);
        }
    }
    /**
     * 解析shp文件
     */
    private ParsingResult analysisShp(AttachmentInfoEntity attach) throws Exception {
        String fileName = attach.getFileDirId()+attach.getAttachPath();
        //解析shp文件
        ArrayList<MultipartFile> multipartFiles = ZipUtils.decompress(fileName);
        String prj = "";
        String shp = "";
        String root = StrUtil.removeSuffix(fileName,".zip");
        for (MultipartFile multipartFile : multipartFiles) {
            String originalFilename = multipartFile.getOriginalFilename();
            assert originalFilename != null;
            if(originalFilename.contains(".prj")){
                prj = root + File.separator + originalFilename;
            }
            if(originalFilename.contains(".shp") && !originalFilename.contains(".shp.xml")){
                shp = root + File.separator + originalFilename;
            }
        }
        ParsingResult shpData = ShpAnalyticUtil.analytic(prj, "UTF-8", shp);
        if (!shpData.getMessage().equals("ok")) {
            throw new RuntimeException(shpData.getMessage());
        }
        //删除解压的文件
        ZipUtils.delFolder(root);
        return shpData;
    }
    /**
     * 构建造价实体数据
     */
    private List<EconomyBuildingPrice> getList(List<List<Object>> shpList) throws Exception {
        List<EconomyBuildingPrice> resultList = new ArrayList<>();

        //获取上传文件的坐标系 用于保存数据时的坐标系

        //不同烈度的数据放在了同一行，保存时一个烈度的数据一行数据
        for (int i = 0; i < shpList.size(); i++) {
            List<Object> list = shpList.get(i);
            String code = getZbx(list);
            PGgeometry pGgeometry = new PGgeometry(ShpAnalyticUtil.checkGeomTypeOf(list.get(0).toString(), GeomTypeEnum.MULTIPOLYGON));
            Geometry geometry = pGgeometry.getGeometry();
            geometry.setSrid(Integer.parseInt(code));
            int index = 2;
            EconomyBuildingPrice economyBuildingPrice = new EconomyBuildingPrice();
            economyBuildingPrice.setId(UUID.randomUUID().toString().replace("-",""))
                    .setGeom(geometry.toString()).setCode("4490").setGanghunRatio(Double.parseDouble(ShpAnalyticUtil.getStringVal(list.get(index++), "钢混造价", true)))
                    .setQitiRatio(Double.parseDouble(ShpAnalyticUtil.getStringVal(list.get(index++), "砌体造价", true)))
                    .setDangcengRatio(Double.parseDouble(ShpAnalyticUtil.getStringVal(list.get(index++), "砌体造价", true)))
                    .setQitaRatio(Double.parseDouble(ShpAnalyticUtil.getStringVal(list.get(index++), "砌体造价", true)));
            resultList.add(economyBuildingPrice);
        }
        return resultList;
    }

    /**
     * 获取坐标系
     */
    private String getZbx(List<Object> shpList){
        int size = shpList.size();
        String code = "4490";
        if(ObjectUtils.isNotEmpty(shpList.get(size-1))){
            code = (String) shpList.get(size-1);
        }
        return code;
    }

    @Override
    public EconomyModel details() {
        EconomyModel economyModel = this.baseMapper.selectOne(null);
        if(StringUtils.isNotBlank(economyModel.getAttachId())){
            economyModel.setVos(getAttach(economyModel.getAttachId()));
        }
        //获取损失比矩阵
        List<BuildingLossMatrix> list = buildingLossMatrixService.list(null);
        economyModel.setList(list);
        return economyModel;
    }

    private List<AttachVO> getAttach(String attachId){
        String[] idSplit = attachId.split(",");
        List<AttachVO> list = new ArrayList<>();
        for (String aid : idSplit) {
            AttachmentInfoEntity attach = attachmentService.getAttach(aid);
            AttachVO attachVO = new AttachVO();
            attachVO.setAttachId(aid);
            attachVO.setAttachName(attach.getAttachName());
            list.add(attachVO);
        }
        return list;
    }
}
